package edu.wpi.cs509.representation;

import java.io.Serializable;

/**
 * Location information
 *
 * This class is describes a location on either the game board or boneyard.
 * 
 * Location 0,0 is located on the bottom left corner of the Red player's side
 * of the game board.
 * 
 * @author Jay Lubomirski
 * @see edu.wpi.cs509.representation.Gameboard
 */
public class Location extends StrategoObjectBc implements Serializable {
	private static final long serialVersionUID = 1L; // version of structure for messages
	int x; // valid if on game board and boneyard = false
	int y; // valid if on game board and boneyard = false
	boolean boneyard; // true if piece is in boneyard
	int index; // valid if on gameboard, index refers to a board square. boardsquare 0,0 = index 0, 9,9 = 99, 100 < index < 0 invalid	
		
	// X & Y coordinates for lake locations on board
	static final int LakeY[] = { 4, 5 };
	static final int LakeX[] = { 2, 3, 6, 7 };
	
	/**
	 * Constructor if location is on game board
	 * @param xCoordinate x location on game board
	 * @param yCoordinate y location on game board
	 *
	 * @throws IllegalArgumentException if the coordinates
	 * are out of range.
	 */
	public Location(int xCoordinate, int yCoordinate) {
		super("Location (" + xCoordinate + "," + yCoordinate + ")");
		
		if ((xCoordinate > 9) || (xCoordinate < 0))
			throw new IllegalArgumentException("xCoordinate " + xCoordinate + " is not valid");
		
		if ((yCoordinate > 9) | (yCoordinate < 0))
			throw new IllegalArgumentException("yCoordinate " + yCoordinate + " is not valid");
		
		x = xCoordinate;
		y = yCoordinate;
		boneyard = false;
		index = (x*10)+y;
	}
	
	/** 
	 * Constructor if location is in boneyard
	 */
	public Location() {
		super("Location boneyard");
		x = -1;
		y = -1;
		index = -1;
		boneyard = true;
	}
	
	/**
	 * Return a printable string version of the location.
	 */
	public String toString() {
		if (boneyard == true)
			return ("boneyard");
		else
			return ("(" + x + "," + y + ")");
	}

	/** 
	 * Get the x coordinate.
	 * @return x value of current location.
	 * 
	 * @throws IndexOutOfBoundsException if the piece is in the boneyard
	 */
	public int getXCoordinate() {
		if (boneyard == true)
				throw new IndexOutOfBoundsException("Piece is in boneyard");
		return (x);
	}
	
	/** 
	 * Get the y coordinate.
	 * @return y value of current location.
	 * 
	 * @throws IndexOutOfBoundsException if the piece is in the boneyard
	 */
	public int getYCoordinate() {
		if (boneyard == true)
			throw new IndexOutOfBoundsException("Piece is in boneyard");
		return (y);
	}
	
	/**
	 * Get the game board index for piece.
	 * @return game board index
	 * 
	 * @throws IndexOutOfBoundsException if the piece is in the boneyard
	 */
	public int getIndex() {
		if (boneyard == true)
			throw new IndexOutOfBoundsException("Piece is in boneyard");
		return index;
	}
	
	/** 
	 * Determine if location is one of the lake locations on the board.  
	 * @return true if location is in the lake.
	 *
	 * @throws IndexOutOfBoundsException if the piece is in the boneyard
	 */
	public boolean isLake() {
		boolean isLakey = false;
		boolean isLakex = false;

		if (boneyard == true)
			throw new IndexOutOfBoundsException("Piece is in boneyard");

		
		for (int yidx = 0; yidx < LakeY.length; yidx++) {
			if (y == LakeY[yidx])
				isLakey = true;
		}
		
		if (isLakey == true) {
			for (int xidx = 0; xidx < LakeX.length; xidx++) {
				if (x == LakeX[xidx])
					isLakex = true;
			}
		}
		
		return (isLakey && isLakex);
	}
	
	/**
	 * Determine if a piece can theoretically be placed in this location
	 * @return true if this square can hold a piece.
	 */
	public boolean isOccupiable() {
		return !isLake(); 
	}

	/** 
	 * Determine if piece is in boneyard.
	 * @return true if piece is in boneyard.
	 * 
	 * @throws IllegalStateException if the piece is
	 * in the boneyard and has x & y coordinates
	 */
	public boolean isInBoneyard() {
		if ((x != -1) && (y != -1) && boneyard)
			throw new IllegalStateException("Piece is in bone yard and on game board");
		return (boneyard);	
	}

	public boolean isValidBoardLocation() {
		
		if ((x<0) || (x>9)) return false;
		if ((y<0) || (y>9)) return false;
		
		return true;

	}
}
